package com.whsxt.service.impl;

import com.whsxt.common.CodeMsg;
import com.whsxt.domain.Permission;
import com.whsxt.dto.PermissionDto;
import com.whsxt.exception.BusinessException;
import com.whsxt.mapper.PermissionMapper;
import com.whsxt.service.PermissionService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.List;

@Service
public class PermissionServiceImpl implements PermissionService {

    @Autowired
    private PermissionMapper permissionMapper;

    /**
     * 查询所有的权限信息
     * @return
     */
    @Override
    public List<Permission> selectAll( List<Integer> types) {
        return permissionMapper.selectAll(types);
    }

    /**
     * 批量删除权限
     * @param ids
     * @return
     */
    @Override
    @Transactional
    public boolean batchRemove(List<Integer> ids) {
        // 1.校验数据
        // 首先判断获取的id数据是否为空
        if(CollectionUtils.isEmpty(ids)){
            throw new IllegalArgumentException("需要删除的数据不能为空");
        }
        // 采用循环删除来实现批量删除
        int rows = 0;
        for (Integer id : ids){
            rows += delete(id);
        }
        return rows > 0;
    }

    /**
     * 删除单个权限
     * @param id
     * @return
     */
    private int delete(Integer id){
        // 判断要删除的元素是否有父亲
        int count = permissionMapper.selectCountByPid(id);
        if(count > 0){
            throw new IllegalArgumentException("要删除权限的子节点不能为空");
        }

        // 删除权限
        return permissionMapper.deleteByPrimaryKey(id);
    }

    /**
     * 添加权限数据
     * @param permissionDto 要添加的权限对象数据
     * @return
     */
    @Override
    public boolean save(PermissionDto permissionDto) {
        // 1.进行数据的校验
        validate(permissionDto);
        // 2.进行属性的拷贝
        Permission permission = new Permission();
        BeanUtils.copyProperties(permissionDto, permission);
        // 3.进行属性的填充(无)
        // 4.执行方法
        int row = permissionMapper.insert(permission);
        return row > 0;
    }

    /**
     * 修改权限数据
     * @param permissionDto
     * @return
     */
    @Override
    public boolean update(PermissionDto permissionDto) {
        // 判断要修改的数据是否存在
        Permission permission = permissionMapper.selectByPrimaryKey(permissionDto.getId());
        if(null == permission){
            throw new IllegalArgumentException("要修改的数据不存在");
        }
        // 校验数据
        // 判断是否修改了权限类型
        if(!permission.getType().equals(permissionDto.getType())){
            throw new IllegalArgumentException("类型不匹配");
        }

        // 判断父节点是否匹配
        if(!permission.getParentId().equals(permissionDto.getParentId())){
            throw new IllegalArgumentException("父节点不匹配");
        }

        Permission update = new Permission();
        // 拷贝属性
        BeanUtils.copyProperties(permissionDto, update);
        // 填充默认值(无)
        // 修改值
        int rows = permissionMapper.updateByPrimaryKey(update);
        return rows > 0;
    }

    /**
     * 通过角色id查询出权限数据id
     *
     * @param roleId
     * @return
     */
    @Override
    public List<Integer> selectPermsByRoleId(Integer roleId) {
        List<Integer> permIds = permissionMapper.selectPermsByRoleId(roleId);
        return CollectionUtils.isEmpty(permIds)? Collections.emptyList() : permIds;
    }

    /**
     * 通过用户id查询出菜单数据
     * @param userId
     * @param types
     * @return
     */
    @Override
    public List<Permission> selectPermsByUserId(Integer userId, List<Integer> types) {
        return permissionMapper.selectPermsByUserId(userId, types);
    }

    /**
     * 进行数据的校验
     * @param permissionDto
     * 校验规则:
     *  当类型为目录时规则为：
     *    父 id = 0
     *    链接为空
     * 当类型为菜单时
     *    父id不为0 ，而且必须存在
     *    链接不能为空
     * 当类型为按钮时
     *   父id不为0 ，而且必须存在
     *   链接为空
     *   标识 不为空
     */
    private void validate(PermissionDto permissionDto){

        Integer type = permissionDto.getType();
        if(type == null){
            throw new IllegalArgumentException("输入的类型不合法");
        }
        // 目录的校验
        if(type == 0){
            permissionDto.setParentId(0);
            permissionDto.setHref(null);
        }
        // 菜单校验
        if(type == 1){
            if(permissionDto.getParentId() == 0 || permissionDto.getParentId() == null){
                throw new IllegalArgumentException("父菜单的ID不能为空");
            }
            if(!StringUtils.hasText(permissionDto.getHref())){
                throw new IllegalArgumentException("链接地址不能输入为空");
            }
            permissionDto.setTag(null);
        }
        // 按钮校验
        if(type == 2){
            if(permissionDto.getParentId() == 0 || permissionDto.getParentId() == null){
                throw new IllegalArgumentException("父菜单的ID不能为空");
            }
            if(!StringUtils.hasText(permissionDto.getTag())){
                throw new IllegalArgumentException("标识不能输入为空");
            }
            permissionDto.setHref(null);
        }

        // 权限标识不能重复的校验
        if(StringUtils.hasText(permissionDto.getTag())){
            int count = permissionMapper.selectCountByTag(permissionDto.getTag());
            if(count > 0){
                throw new BusinessException(CodeMsg.PERMISSION_TAG_FOUND,permissionDto.getTag());
            }
        }
    }

}
